#pragma once
// Mysql版本
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <fstream>
#include "../comm/Log.hpp"
#include "../comm/util.hpp"
#include <cstdlib>
#include <cassert>

#include "include/mysql.h"

namespace oj_model
{
    using namespace std;
    using namespace ns_log;
    using namespace ns_util;

    // 1 回文数 简单 ./oj_questions/1 1 5000
    struct Question
    {
        string _num;
        string _title;
        string _star;
        int _cpu_rlimit;
        int _mem_rlimit;
        string _desc;
        string _header;
        string _tail;
    };

    const string oj_questions = "oj_questions";
    const string host = "127.0.0.1";
    const string user = "oj_client";
    const string passwd = "123456";
    const string db = "oj";
    const int port = 3306;

    class Model
    {
    public:
        Model()
        {
        }
        ~Model()
        {
        }

        // 根据题目list文件，加载所有的题目信息到内存中
        //  model: 主要用来和数据进行交互，对外提供访问数据的接口

        bool QuestionsMysqlLoad(const string &sql, vector<Question> *out)
        {
            // mysql句柄
            MYSQL *my = mysql_init(nullptr);
            // 连接
            if(nullptr == mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0))
            {
                LOG(FATAL, "连接数据库失败！！！: %s",mysql_error(my));
                return false;
            }
            LOG(INFO, "连接数据库成功");

            // 编码设置
            mysql_set_character_set(my, "utf8");

            // 执行语句
            if (0 != mysql_query(my, sql.c_str()))
            {
                LOG(WARNNING, "sql : %s 语句执行失败!", sql.c_str());
                return false;
            }
            LOG(INFO, "sql语句执行成功");

            // 获取结果
            MYSQL_RES *res = mysql_store_result(my);

            // 提取结果
            int rows = mysql_num_rows(res);   // 行数
            int cols = mysql_num_fields(res); // 列数

            Question q;
            for (int i = 0; i < rows; i++)
            {
                MYSQL_ROW row = mysql_fetch_row(res); // 提取行结果
                for (int j = 0; j < cols; j++)
                {
                    q._num = row[0];
                    q._title = row[1];
                    q._star = row[2];
                    q._desc = row[3];
                    q._header = row[4];
                    q._tail = row[5];
                    q._cpu_rlimit = atoi(row[6]);
                    q._mem_rlimit = atoi(row[7]);
                }
                out->push_back(q);
            }
            free(res);
            mysql_close(my);

            return true;
        }
        bool GetAllQuestions(vector<Question> *out)
        {
            string sql = "select * from ";
            sql += oj_questions;
            return QuestionsMysqlLoad(sql, out);
        }

        bool GetOneQuestion(const string &num, Question *q)
        {
            bool ret = false;
            string sql = "select * from ";
            sql += oj_questions;
            sql += " where num = ";
            sql += num;

            vector<Question> out;
            if (QuestionsMysqlLoad(sql, &out))
            {
                // 取到了我要的
                if (out.size() == 1)
                {
                    *q = out[0];
                    ret = true;
                }
            }
            return ret;
        }

    private:
        unordered_map<string, Question> _questionsmap;
    };
};